﻿using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SqlSugarCoreDemo.DBSqlSugar
{
    public static class SqlSugarSetup
    {
        public static void AddSqlSugarSetup(this IServiceCollection services)
        {
            #region SqlSugarClient配置=======================
            //写入主数据库地址
            string mainConn = "server=127.0.0.1;uid=sqlsugar_user;pwd=sqlsugar_www;database=SqlSugarCoreDemo;";
            //读取从数据库地址
            List<string> listReadConn = new List<string>()
            {
                "server=127.0.0.1;uid=sqlsugar_user_read;pwd=sqlsugar_zzzz;database=SqlSugarCoreDemo;"
            };
            var listSlaveConn = new List<SlaveConnectionConfig>();
            foreach (string item in listReadConn)
            {
                //HitRate 越大走这个从库的概率越大
                listSlaveConn.Add(new SlaveConnectionConfig() { HitRate = 10, ConnectionString = item });
            }

            //数据库类型
            var dbType = DbType.SqlServer;

            //开启Redis设置二级缓存方式
            //ICacheService myCache = ConfigurationVars.RedisUseCache ? (ICacheService)new SqlSugarRedisCache() : new SqlSugarMemoryCache();
            //连接配置
            var connectionConfig = new ConnectionConfig()
            {
                //主数据库
                ConnectionString = mainConn,
                //数据库类型
                DbType = dbType,
                //自动释放数据事务，如果存在事务，在事务结束后释放
                IsAutoCloseConnection = true,
                //从实体特性中读取主键自增列信息,Attribute用于DbFirst,从数据库生成model的
                InitKeyType = InitKeyType.Attribute,
                //InitKeyType = InitKeyType.SystemTable SystemTable用于Codefirst 从model库生成数据库表的

                //配置扩展服务
                //ConfigureExternalServices = new ConfigureExternalServices()
                //{
                //    DataInfoCacheService = myCache
                //},
                //读取从数据库地址(读写分离有pwd丢失问题，等后面解决了在开放)
                SlaveConnectionConfigs = listSlaveConn
            };
            #endregion

            //注入容器
            services.AddScoped<ISqlSugarClient>(o =>
            {
                var db = new SqlSugarScope(connectionConfig);

                #region Sql执行拦截器===============================
                //日志处理
                //SQL执行前 可以修改SQL
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    //当前连接数据库
                    string curDbConn = db.CurrentConnectionConfig.ConnectionString;
                    Console.WriteLine("\r\n" + curDbConn);

                    ////获取sql
                    //Console.WriteLine(sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                    //Console.WriteLine();

                    ////通过TempItems这个变量来算出这个SQL执行时间（1）
                    //if (db.TempItems == null) db.TempItems = new Dictionary<string, object>();
                    //db.TempItems.Add("logTime", DateTime.Now);
                    ////通过TempItems这个变量来算出这个SQL执行时间（2）
                    //var startingTime = db.TempItems["logTime"];
                    //db.TempItems.Remove("time");
                    //var completedTime = DateTime.Now;
                };
                ////SQL执行完事件
                //db.Aop.OnLogExecuted = (sql, pars) => {};
                ////SQL执行前事件
                //db.Aop.OnLogExecuting = (sql, pars) => {};

                //执行SQL 错误事件
                db.Aop.OnError = (exp) =>
                {
                    throw new Exception(exp.Message, exp);
                };
                #endregion

                return db;
            });

            //注入Sql工作单元
            services.AddScoped<IUnitOfWork, UnitOfWork>();
        }
    }
}
